/**
 * 人员权限相关功能
 */
import db, { mysql } from 'src-ssr/db/connect';
import TableHelper from 'src-ssr/db/tableHelper';
import * as tools from 'src-ssr/util/common';
import autocode from 'src-ssr/util/autocode';
import shortid from 'shortid';
import md5 from 'md5';
import logs from 'src-ssr/util/logs';
import workflow from 'src-ssr/util/workflow';
import schedule from 'src-ssr/util/schedule';
import { Sequelize, Op, QueryTypes } from 'sequelize';
import models, { sequelize } from 'src-ssr/db/sequelize';
import mDict from 'src-ssr/util/dictionary';

/**
 * 复制权限实现函数
 * @param {*} from_type 源类型 user-用户 role-角色
 * @param {*} from_id 源id 若from_type=user,则为用户id，若from_type=role，则为角色id
 * @param {*} to_type 目标类型 user-用户 role-角色
 * @param {*} to_id 目标id 若to_type=user,则为用户id，若to_type=role，则为角色id
 */
async function copyRightsFromTo (from_type, from_id, to_type, to_id) {
  const fromModel = from_type === 'user' ? models.m_users : models.m_roles;
  const toModel = to_type === 'user' ? models.m_users : models.m_roles;

  const fromRight = await fromModel.findOne({
    attributes: ['rights', 'hash'],
    where: { id: from_id },
    raw: true
  });

  await toModel.update(fromRight, { where: { id: to_id } });
}

// 人员信息列表
export const userList = async (req, res) => {
  let { startRow, count, filter, sortBy, descending } = req.body;

  const user = await tools.getLoginUser(req.get('Authorization').split(' ')[1]);
  const where = [{ tenant_id: filter.tenant_id }], order = [];

  // 非管理员只能查看自己的用户
  if (user.tid > 0 && user.tid != filter.tenant_id) {
    return res.json({
      data: [],
      rowsNumber: 0
    });
  }

  order.push(['state', 'desc']); // 启用排前，停用排后

  if (Object.prototype.toString.call(filter) === '[object Object]' && filter) {
    filter = filter.filter;
  }

  filter && where.push({ nickname: { [Op.like]: `%${filter}%` } });
  sortBy && order.push([sortBy, descending ? 'DESC' : 'ASC']);

  const ret = await models.m_users.findAndCountAll({
    attributes: ['id', 'nickname', 'tel', 'email', 'create_time', 'state', 'last_login_time', 'login_count', 'rights', 'hash',
      [Sequelize.col('m_role.id'), 'role_id'], Sequelize.col('m_role.role_name')],
    include: [{ model: models.m_roles, attributes: [] }],
    where: { [Op.and]: where },
    order: order.length > 0 ? order : undefined,
    offset: startRow,
    limit: count,
    raw: true
  });

  res.json({
    data: ret.rows,
    rowsNumber: ret.count
  });
};

// 保存用户信息
export const saveUser = async (req, res) => {
  const { mode, id, formData } = req.body;

  let ret, data, result = {}, cnt;
  const user = await tools.getLoginUser(req.get('Authorization').split(' ')[1]);

  let right = { func: false };
  if (user) {
    right = await tools.checkUserRight(user, 'user', ['func']);
    if (!right.func) {
      // 是否有功能权限
      return res.json({ result: 'fail', message: '无权限' });
    }
  }

  let tables = [], queries;
  switch (mode) {
    case 'add': // 新增 insertId
      cnt = await models.m_users.count({ where: { nickname: formData.nickname.trim(), tenant_id: formData.tenant_id } });
      if (cnt > 0) {
        result = { result: 'fail', message: '用户名重复' };
      } else {
        data = TableHelper.filterField('m_users', formData);
        data.salt = shortid.generate();
        data.password = md5((formData.password || 'mdy123456') + data.salt);// 空密码设为mdy123456
        data.create_time = parseInt(Date.now() / 1000);
        data.create_user_id = user.id;
        data.create_user_name = user.nickname;
        data.create_ip = tools.getIP(req);

        ret = await models.m_users.create(data);

        // 分配角色的权限
        if (formData.role) {
          await copyRightsFromTo('role', formData.role, 'user', ret.id);
        } else { // 若无角色，则取菜单中的默认权限
          // 默认权限
          const defaultRights = await tools.defaultRights(data.tenant_id > 0 ? 't' : 'm');
          await models.m_users.update({ rights: defaultRights.rights, hash: defaultRights.hash }, { where: { id: ret.id } });
        }

        result = { result: 'ok', id: ret.id };
      }
      logs.recordLogs(user, { type: 'add', model: '人员权限', content: formData.nickname }, req);
      break;
    case 'edit': // 修改
      cnt = await models.m_users.count({ where: { nickname: formData.nickname.trim(), id: { [Op.ne]: id }, tenant_id: formData.tenant_id } });
      if (cnt > 0) {
        result = { result: 'fail', message: '用户名重复' };
      } else {
        data = TableHelper.filterField('m_users', formData);
        ret = await models.m_users.findByPk(id);

        if (data.password) { // 有密码则加密，无密码则取原来密码
          data.password = md5(data.password + ret.salt);
        } else {
          data.password = ret.password;
        }

        await models.m_users.update(data, { where: { id } });
        result = { result: 'ok' };
      }
      // 分配角色的权限
      if (formData.role) await copyRightsFromTo('role', formData.role, 'user', id);

      logs.recordLogs(user, { type: 'edit', model: '人员权限', content: formData.nickname }, req);
      break;
    case 'delete': // 删除
      tables = TableHelper.findTablesByField('create_user_id');
      queries = tables.map(tableModel => {
        return models[tableModel].count({
          where: { create_user_id: id }
        });
      });
      cnt = (await Promise.all(queries)).reduce((sum, count) => sum + count, 0);

      if (cnt > 0) {
        result = { result: 'fail', message: '该用户已操作过数据，不可删除，只能禁用！' };
      } else {
        logs.recordLogs(user, { type: 'delete', model: '人员权限', content: (await models.m_users.findOne({ attributes: ['nickname'], where: { id }, raw: true })).nickname }, req);
        await models.m_users.destroy({ where: { id } });
        result = { result: 'ok' };
      }
      break;
  }
  // console.log(result);
  res.json(result);
}

/**
 * 保存用户权限
 * @param {number} req.body.id 用户id
 * @param {string, object} req.body.rights 用户权限
 */
export const saveUserRights = async (req, res) => {
  const { id, rights } = req.body;
  const hash = tools.rightsHash(rights);

  await models.m_users.update({ rights, hash }, { where: { id } });
  res.json({ result: 'ok', hash });
}

/**
 * 复制权限
 * @param {object} req.body.from 源 例 { type: 'user', id: 1 }
 * @param {object} req.body.to 目标 例 { type: 'user', id: [1,2] }
 */
export const copyRightsTo = async (req, res) => {
  const { from, to } = req.body;
  // const user = await tools.getLoginUser(req.get('Authorization').split(' ')[1]);

  // 权限复制给角色时，检查是否有重复
  if (from.type === 'user' && to.type === 'role') {
    const user = await models.m_users.findOne({
      attributes: [[Sequelize.col('role.id'), 'role_id']],
      include: [{
        model: models.m_roles,
        attributes: []
      }],
      where: { id: from.id },
      raw: true
    });

    if (user.role_id && user.role_id != to.id) {
      return res.json({ result: 'fail', message: '角色权限发生重复，复制失败！' });
    }
  }
  await copyRightsFromTo(from.type, from.id, to.type, to.id);

  res.json({ result: 'ok' });
};

/**
 * 保存角色权限
 * @param {string} req.body.mode 模式 add-新增 edit-修改 delete-删除
 * @param {number} req.body.id id
 * @param {formData} req.body.formData 提交的数据
 */
export const saveRole = async (req, res) => {
  let { mode, id, formData } = req.body;

  let data, result = {};
  const user = await tools.getLoginUser(req.get('Authorization').split(' ')[1]);

  if (formData) {
    if (typeof formData === 'string') {
      formData = JSON.parse(formData);
    }
    if (typeof formData.rights === 'object') {
      formData.rights = JSON.stringify(formData.rights);
    }
  }

  switch (mode) {
    case 'add':
      data = TableHelper.filterField('m_roles', formData);
      await models.m_roles.create(data);
      result = { result: 'ok' };

      logs.recordLogs(user, { type: 'add', model: '角色', content: { formData } }, req);
      break;
    case 'edit':
      data = TableHelper.filterField('m_roles', formData);
      await models.m_roles.update(data, { where: { id } });
      result = { result: 'ok' };

      logs.recordLogs(user, { type: 'edit', model: '角色', content: { formData } }, req);
      break;
    case 'delete': // 删除
      if (id < 10) {
        result = { result: 'fail', message: '不允许删除系统角色' };
      } else {
        logs.recordLogs(user, { type: 'delete', model: '角色', content: await models.m_roles.findOne({ where: { id }, raw: true }) }, req);
        await models.m_roles.destroy({ where: { id } });
        result = { result: 'ok' };
      }

      break;
  }
  res.json(result);
};

/**
 * 保存角色权限
 * @param {number} req.body.id 角色id
 * @param {string, object} req.body.rights 角色权限
 */
export const saveRoleRights = async (req, res) => {
  const { id, rights, tenant_id } = req.body;
  const hash = tools.rightsHash(rights);

  // const user = await tools.getLoginUser(req.get('Authorization').split(' ')[1]);
  const check = await models.m_roles.findOne({
    where: {
      id: { [Op.ne]: id },
      hash,
      tenant_id
    }
  });

  if (check) {
    return res.json({ result: 'fail', message: `权限与 ${check.role_name} 发生重复，请重新配置` });
  }

  // 把之前相同权限的用户都跟着一起更新权限
  const roleInfo = await models.m_roles.findByPk(id);
  await models.m_users.update({ rights, hash }, { where: { hash: roleInfo.hash, tenant_id } });
  await models.m_roles.update({ rights, hash }, { where: { id } });

  res.json({ result: 'ok' });
}

/**
 * 取角色列表
 */
export const roleList = async (req, res) => {
  const { startRow, count, filter, sortBy, descending } = req.body;
  const { tenant_id } = filter;
  let query = '';

  const user = await tools.getLoginUser(req.get('Authorization').split(' ')[1]);
  const where = [`r.tenant_id=${tenant_id}`], order = [];

  // 非管理员只能查看自己的角色
  if (user.tid > 0 && user.tid != tenant_id) {
    return res.json({
      data: [],
      rowsNumber: 0
    });
  }

  if (Object.prototype.toString.call(filter) === '[object Object]' && filter && filter.filter) {
    query = filter.filter;
  }

  if (filter) where.push('role_name like ?');
  sortBy && order.push(`${sortBy} ${descending ? 'DESC' : ''}`);
  const limit = count ? `LIMIT ${startRow}, ${count}` : '';

  const rowsNumber = await models.m_roles.count({ where: { role_name: { [Op.like]: `%${query || ''}%` }, tenant_id } });

  const rows = await sequelize.query(`SELECT * FROM (
      SELECT r.id, r.role_name, r.rights, r.hash,
      u.user_detail, u.user_count, a.repeat_count, a.repeat_name
      FROM m_roles r
      LEFT JOIN (
        SELECT hash, JSON_ARRAYAGG(JSON_OBJECT(
          'id', id,
          'nickname', nickname
        )) user_detail,
        COUNT(*) user_count
        FROM m_users
        WHERE tenant_id=${tenant_id}
        GROUP BY hash
      ) u ON r.hash=u.hash
      LEFT JOIN (
        SELECT hash, COUNT(*) repeat_count, GROUP_CONCAT(role_name) repeat_name
        FROM m_roles
        WHERE tenant_id=${tenant_id}
        GROUP BY hash
      ) a ON r.hash=a.hash
      ${where.length > 0 ? ' WHERE ' + where.join(' AND ') : ''}
    ) a
    ${order.length > 0 ? ' ORDER BY ' + order.join(',') : ''}
    ${limit}`, {
    replacements: [`%${query}%`],
    type: QueryTypes.SELECT,
    raw: true
  });

  res.json({
    data: rows,
    rowsNumber
  });
};
